<!DOCTYPE html>
<!-- saved from url=(0073)#t408.git%20hooks -->
<html lang="en">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>vite</title>
  <link rel="stylesheet" type="text/css" href="./typescript6/main.css">
  <link rel="stylesheet" href="./typescript6/bootstrapmin_1645176572503.css">
  <style>
    .page-toc>ul .red {
      background: #f3f3f3;
      z-index: 1;
      border-left: 3px solid #009a61;
      -webkit-transition: all .2s ease;
      transition: all .2s ease;
      color: #000
    }
  </style>
</head>

<body>

  <div class="warpper">
    <div class="page-toc">
      <ul>
        <li><a href="#t01.%E8%AF%BE%E7%A8%8B%E5%A4%A7%E7%BA%B2">1.课程大纲</a>
          <ul>
            <li><a href="#t11.1%20Vite2+Vue3+Typescript%20%E6%90%AD%E5%BB%BA%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83"
                class="">1.1 Vite2+Vue3+Typescript 搭建开发环境</a></li>
            <li><a
                href="#t21.2%20rollup%E5%92%8Cvite2%E6%8F%92%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%92%8C%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8F%92%E4%BB%B6">1.2
                rollup和vite2插件系统和自定义插件</a></li>
            <li><a href="#t31.3%20%E4%BB%8E%E9%9B%B6%E5%AE%9E%E7%8E%B0vite2">1.3
                从零实现vite2</a></li>
          </ul>
        </li>
        <li><a href="#t42.%E5%AE%89%E8%A3%85%20vite">2.安装
            vite</a>
          <ul>
            <li><a href="#t52.1%20vite%20%E4%BB%8B%E7%BB%8D">2.1
                vite 介绍</a></li>
            <li><a href="#t62.2%20vite%20%E5%AE%89%E8%A3%85">2.2
                vite 安装</a></li>
          </ul>
        </li>
        <li><a href="#t73.%E5%90%AF%E5%8A%A8%20vite">3.启动
            vite</a>
          <ul>
            <li><a href="#t83.1%20package.json">3.1
                package.json</a></li>
            <li><a href="#t93.2%20vite.config.js" class="">3.2
                vite.config.js</a></li>
            <li><a href="#t103.3%20index.html">3.3
                index.html</a></li>
            <li><a href="#t113.4%20src\env.d.ts">3.4
                src\env.d.ts</a></li>
            <li><a href="#t123.5%20src\main.ts">3.5
                src\main.ts</a></li>
            <li><a href="#t133.6%20tsconfig.json">3.6
                tsconfig.json</a></li>
            <li><a href="#t143.7%20.gitignore">3.7
                .gitignore</a></li>
          </ul>
        </li>
        <li><a href="#t154.%E6%94%AF%E6%8C%81%20vue3">4.支持
            vue3</a>
          <ul>
            <li><a href="#t164.1%20%E5%AE%89%E8%A3%85%20vue">4.1
                安装 vue</a></li>
            <li><a href="#t174.2%20vite.config.ts">4.2
                vite.config.ts</a></li>
            <li><a href="#t184.3%20src\env.d.ts">4.3
                src\env.d.ts</a></li>
            <li><a href="#t194.4%20src\main.ts">4.4
                src\main.ts</a></li>
            <li><a href="#t204.5%20src\App.vue">4.5
                src\App.vue</a></li>
            <li><a href="#t214.6%20HelloWorld.vue">4.6
                HelloWorld.vue</a></li>
          </ul>
        </li>
        <li><a href="#t225.%E6%94%AF%E6%8C%81%20typescript">5.支持
            typescript</a>
          <ul>
            <li><a href="#t235.1%20%E5%AE%89%E8%A3%85">5.1
                安装</a></li>
            <li><a href="#t245.2%20package.json">5.2
                package.json</a></li>
            <li><a href="#t255.3%20msg.ts">5.3 msg.ts</a></li>
            <li><a href="#t265.4%20App.vue">5.4 App.vue</a></li>
          </ul>
        </li>
        <li><a href="#t276.ESLint">6.ESLint</a>
          <ul>
            <li><a href="#t286.1%20%E5%AE%89%E8%A3%85">6.1
                安装</a></li>
            <li><a href="#t296.2%20.eslintrc.js" class="my-active">6.2 .eslintrc.js</a></li>
            <li><a href="#t306.3%20.eslintignore">6.3
                .eslintignore</a></li>
            <li><a href="#t316.4%20package.json">6.4
                package.json</a></li>
          </ul>
        </li>
        <li><a href="#t327.Prettier">7.Prettier</a>
          <ul>
            <li><a href="#t337.1%20%E5%AE%89%E8%A3%85">7.1
                安装</a></li>
            <li><a href="#t347.2%20.eslintrc.js">7.2
                .eslintrc.js</a></li>
            <li><a href="#t357.3%20.prettierrc.js">7.3
                .prettierrc.js</a></li>
            <li><a href="#t367.4%20.prettierignore">7.4
                .prettierignore</a></li>
            <li><a href="#t377.5%20editorconfig">7.5
                editorconfig</a>
              <ul>
                <li><a href="#t387.5.1%20.editorconfig">7.5.1
                    .editorconfig</a></li>
              </ul>
            </li>
            <li><a href="#t397.6%20%E8%87%AA%E5%8A%A8%E6%A0%BC%E5%BC%8F%E5%8C%96">7.6
                自动格式化</a></li>
          </ul>
        </li>
        <li><a href="#t408.git%20hooks">8.git hooks</a>
          <ul>
            <li><a href="#t418.1%20lint-staged">8.1
                lint-staged</a>
              <ul>
                <li><a href="#t428.1.1%20%E5%AE%89%E8%A3%85">8.1.1
                    安装</a></li>
                <li><a href="#t438.1.2%20package.json">8.1.2
                    package.json</a></li>
              </ul>
            </li>
            <li><a href="#t448.2%20commitlint">8.2
                commitlint</a>
              <ul>
                <li><a href="#t458.2.1%20type">8.2.1 type</a>
                </li>
                <li><a href="#t468.2.2%20%E5%AE%89%E8%A3%85">8.2.2
                    安装</a></li>
                <li><a href="#t478.2.3%20%E9%85%8D%E7%BD%AE">8.2.3
                    配置</a></li>
                <li><a href="#t488.2.4%20commitlint.config.js">8.2.4
                    commitlint.config.js</a></li>
              </ul>
            </li>
          </ul>
        </li>
        <li><a href="#t499.%E9%85%8D%E7%BD%AE%E5%88%AB%E5%90%8D">9.配置别名</a>
          <ul>
            <li><a href="#t509.1%20vite.config.ts">9.1
                vite.config.ts</a></li>
            <li><a href="#t519.2%20tsconfig.json">9.2
                tsconfig.json</a></li>
            <li><a href="#t529.3%20App.vue">9.3 App.vue</a></li>
          </ul>
        </li>
        <li><a href="#t5310.%E6%A0%B7%E5%BC%8F%E5%A4%84%E7%90%86">10.样式处理</a>
          <ul>
            <li><a href="#t5410.1%20%E5%85%A8%E5%B1%80%E6%A0%B7%E5%BC%8F">10.1
                全局样式</a>
              <ul>
                <li><a href="#t5510.1.1%20src\global.css">10.1.1
                    src\global.css</a></li>
                <li><a href="#t5610.1.2%20src\main.ts">10.1.2
                    src\main.ts</a></li>
              </ul>
            </li>
            <li><a href="#t5710.2%20%E5%B1%80%E9%83%A8%E6%A0%B7%E5%BC%8F">10.2
                局部样式</a>
              <ul>
                <li><a href="#t5810.2.1%20HelloWorld.vue">10.2.1
                    HelloWorld.vue</a></li>
              </ul>
            </li>
            <li><a href="#t5910.3%20CSS%20Modules">10.3 CSS
                Modules</a>
              <ul>
                <li><a href="#t6010.3.1%20%E5%86%85%E8%81%94">10.3.1
                    内联</a>
                  <ul>
                    <li><a href="#t6110.3.1.1%20HelloWorld.vue">10.3.1.1
                        HelloWorld.vue</a></li>
                  </ul>
                </li>
                <li><a href="#t6210.3.2%20%E5%A4%96%E8%81%94">10.3.2
                    外联</a>
                  <ul>
                    <li><a href="#t6310.3.2.1%20HelloWorld.module.css">10.3.2.1
                        HelloWorld.module.css</a></li>
                    <li><a href="#t6410.3.2.2%20HelloWorld.vue">10.3.2.2
                        HelloWorld.vue</a></li>
                  </ul>
                </li>
              </ul>
            </li>
            <li><a href="#t6510.4%20%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8">10.4
                预处理器</a>
              <ul>
                <li><a href="#t6610.4.1%20%E5%AE%89%E8%A3%85">10.4.1
                    安装</a></li>
                <li><a href="#t6710.4.2%20src\components\HelloWorld.vue">10.4.2
                    src\components\HelloWorld.vue</a></li>
              </ul>
            </li>
            <li><a href="#t6810.5%20%E5%85%A8%E5%B1%80%E6%B3%A8%E5%85%A5">10.5
                全局注入</a>
              <ul>
                <li><a href="#t6910.5.1%20vite.config.ts">10.5.1
                    vite.config.ts</a></li>
                <li><a href="#t7010.5.2%20src\styles\theme.less">10.5.2
                    src\styles\theme.less</a></li>
                <li><a href="#t7110.5.3%20src\styles\theme.scss">10.5.3
                    src\styles\theme.scss</a></li>
                <li><a href="#t7210.5.4%20src\components\HelloWorld.vue">10.5.4
                    src\components\HelloWorld.vue</a></li>
              </ul>
            </li>
            <li><a href="#t7310.6%20PostCSS">10.6 PostCSS</a>
              <ul>
                <li><a href="#t7410.6.1%20%E5%AE%89%E8%A3%85">10.6.1
                    安装</a></li>
                <li><a href="#t7510.6.2%20postcss.config.js">10.6.2
                    postcss.config.js</a></li>
                <li><a href="#t7610.6.3%20.browserslistrc">10.6.3
                    .browserslistrc</a></li>
                <li><a href="#t7710.6.4%20HelloWorld.vue">10.6.4
                    HelloWorld.vue</a></li>
              </ul>
            </li>
          </ul>
        </li>
        <li><a href="#t7811.%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E5%A4%84%E7%90%86">11.静态资源处理</a>
          <ul>
            <li><a href="#t7911.1%20%E6%A8%A1%E6%9D%BF%E5%BC%95%E5%85%A5">11.1
                模板引入</a></li>
            <li><a href="#t8011.2%20JS%20%E4%B8%AD%E5%BC%95%E5%85%A5">11.2
                JS 中引入</a></li>
            <li><a href="#t8111.3%20CSS%20%E5%BC%95%E5%85%A5">11.3
                CSS 引入</a></li>
            <li><a href="#t8211.4%20public%20%E7%9B%AE%E5%BD%95">11.4
                public 目录</a></li>
          </ul>
        </li>
        <li><a href="#t8312.%20mock">12. mock</a>
          <ul>
            <li><a href="#t8412.1%20%E5%AE%89%E8%A3%85">12.1
                安装</a></li>
            <li><a href="#t8512.2%20vite.config.ts">12.2
                vite.config.ts</a></li>
            <li><a href="#t8612.3%20mock\auth.ts">12.3
                mock\auth.ts</a></li>
          </ul>
        </li>
        <li><a href="#t8713.%20%E5%B0%81%E8%A3%85%E8%AF%B7%E6%B1%82">13.
            封装请求</a>
          <ul>
            <li><a href="#t8813.1%20%E5%AE%89%E8%A3%85">13.1
                安装</a></li>
            <li><a href="#t8913.2%20mock\auth.ts">13.2
                mock\auth.ts</a></li>
            <li><a href="#t9013.3%20http.ts">13.3 http.ts</a>
            </li>
            <li><a href="#t9113.4%20src\api\auth.ts">13.4
                src\api\auth.ts</a></li>
            <li><a href="#t9213.5%20auth.ts">13.5 auth.ts</a>
            </li>
            <li><a href="#t9313.6%20src\request.ts">13.6
                src\request.ts</a></li>
            <li><a href="#t9413.7%20main.ts">13.7 main.ts</a>
            </li>
          </ul>
        </li>
        <li><a href="#t9514.%20%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86">14.
            状态管理</a>
          <ul>
            <li><a href="#t9614.1%20%E5%AE%89%E8%A3%85">14.1
                安装</a></li>
            <li><a href="#t9714.2%20src\main.ts">14.2
                src\main.ts</a></li>
            <li><a href="#t9814.3%20store\index.ts">14.3
                store\index.ts</a></li>
            <li><a href="#t9914.4%20HelloWorld.vue">14.4
                HelloWorld.vue</a></li>
          </ul>
        </li>
        <li><a href="#t10015.%20%E8%B7%AF%E7%94%B1">15. 路由</a>
          <ul>
            <li><a href="#t10115.1%20%E5%AE%89%E8%A3%85">15.1
                安装</a></li>
            <li><a href="#t10215.2%20router\index.ts">15.2
                router\index.ts</a></li>
            <li><a href="#t10315.3%20HomePage.vue">15.3
                HomePage.vue</a></li>
            <li><a href="#t10415.4%20LoginPage.vue">15.4
                LoginPage.vue</a></li>
            <li><a href="#t10515.5%20src\main.ts">15.5
                src\main.ts</a></li>
            <li><a href="#t10615.6%20App.vue">15.6 App.vue</a>
            </li>
          </ul>
        </li>
        <li><a href="#t10716.%20UI%20%E7%BB%84%E4%BB%B6%E5%BA%93">16.
            UI 组件库</a>
          <ul>
            <li><a href="#t10816.1%20%E5%AE%89%E8%A3%85">16.1
                安装</a></li>
            <li><a href="#t10916.2%20src\App.vue">16.2
                src\App.vue</a></li>
          </ul>
        </li>
        <li><a href="#t11017.%20%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E5%92%8C%E6%A8%A1%E5%BC%8F">17.
            环境变量和模式</a>
          <ul>
            <li><a href="#t11117.1%20.env.development">17.1
                .env.development</a></li>
            <li><a href="#t11217.2%20.env.production">17.2
                .env.production</a></li>
            <li><a href="#t11317.3%20src\main.ts">17.3
                src\main.ts</a></li>
            <li><a href="#t11417.4%20package.json">17.4
                package.json</a></li>
          </ul>
        </li>
      </ul>
    </div>
    <div class="content markdown-body">
      <h2 id="t01.课程大纲">1.课程大纲 <a href="#t01.%E8%AF%BE%E7%A8%8B%E5%A4%A7%E7%BA%B2"> #
        </a></h2>
      <h3 id="t11.1 Vite2+Vue3+Typescript 搭建开发环境">1.1 Vite2+Vue3+Typescript 搭建开发环境 <a
          href="#t11.1%20Vite2+Vue3+Typescript%20%E6%90%AD%E5%BB%BA%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83">
          # </a></h3>
      <ul>
        <li>安装使用vite2</li>
        <li>支持vue3</li>
        <li>支持typescript</li>
        <li>支持eslint、prettier和editorconfig</li>
        <li>git hooks </li>
        <li>别名</li>
        <li>样式</li>
        <li>静态资源</li>
        <li>mock</li>
        <li>axios请求封装</li>
        <li>pinia状态管理 </li>
        <li>路由</li>
        <li>NaïveUI组件库</li>
        <li>环境变量和模式</li>
      </ul>
      <h3 id="t21.2 rollup和vite2插件系统和自定义插件">1.2 rollup和vite2插件系统和自定义插件 <a
          href="#t21.2%20rollup%E5%92%8Cvite2%E6%8F%92%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%92%8C%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8F%92%E4%BB%B6">
          # </a></h3>
      <h3 id="t31.3 从零实现vite2">1.3 从零实现vite2 <a href="#t31.3%20%E4%BB%8E%E9%9B%B6%E5%AE%9E%E7%8E%B0vite2">
          # </a></h3>
      <h2 id="t42.安装 vite">2.安装 vite <a href="#t42.%E5%AE%89%E8%A3%85%20vite"> # </a></h2>
      <h3 id="t52.1 vite 介绍">2.1 vite 介绍 <a href="#t52.1%20vite%20%E4%BB%8B%E7%BB%8D"> # </a></h3>
      <ul>
        <li>Vite (法语意为 "快速的"，发音 /vit/) 是下一代前端开发与构建工具</li>
        <li>💡 极速的服务启动 使用原生 ESM 文件，无需打包!</li>
        <li>⚡️ 轻量快速的热重载 无论应用程序大小如何，都始终极快的模块热重载（HMR）</li>
        <li>🛠️ 丰富的功能 对 TypeScript、JSX、CSS 等支持开箱即用。</li>
        <li>📦 优化的构建 可选 “多页应用” 或 “库” 模式的预配置 Rollup 构建</li>
        <li>🔩 通用的插件 在开发和构建之间共享 Rollup-superset 插件接口。</li>
        <li>🔑 完全类型化的 API 灵活的 API 和完整 TypeScript</li>
      </ul>
      <h3 id="t62.2 vite 安装">2.2 vite 安装 <a href="#t62.2%20vite%20%E5%AE%89%E8%A3%85"> # </a></h3>
      <ul>
        <li><a href="https://pnpm.io/">pnpm</a></li>
        <li><a href="https://vitejs.dev/config">https://vitejs.dev/config</a></li>
      </ul>
      <pre><code class="lang-js">pnpm install vite -D
</code></pre>
      <h2 id="t73.启动 vite">3.启动 vite <a href="#t73.%E5%90%AF%E5%8A%A8%20vite"> # </a></h2>
      <ul>
        <li><a href="https://esbuild.github.io/">https://esbuild.github.io</a></li>
        <li>Vite 主要由两部分组成<ul>
            <li>一个开发服务器，它基于 原生 ES 模块 提供了 丰富的内建功能，如速度快到惊人的 模块热更新（HMR）,Vite 将会使用 <code>esbuild</code>
              预构建依赖。<code>Esbuild</code> 使用 <code>Go</code> 编写，并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍</li>
            <li>一套构建指令，它使用 Rollup 打包你的代码，并且它是预配置的，可输出用于生产环境的高度优化过的静态资源</li>
          </ul>
        </li>
      </ul>
      <p><img src="./typescript6/websocket_1645812565010.png" width="50%">
        <img src="./typescript6/validtejs_1645813926867.png" width="50%"></p>
      <h3 id="t83.1 package.json">3.1 package.json <a href="#t83.1%20package.json"> # </a></h3>
      <pre><code class="lang-json">{
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"dev"</span>: <span class="hljs-string">"vite"</span>,
    <span class="hljs-attr">"build"</span>: <span class="hljs-string">"vite build"</span>
  }
}
</code></pre>
      <h3 id="t93.2 vite.config.js">3.2 vite.config.js <a href="#t93.2%20vite.config.js"> # </a></h3>
      <pre><code class="lang-js"><span class="hljs-keyword">import</span> { defineConfig } <span class="hljs-keyword">from</span> <span class="hljs-string">"vite"</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> defineConfig({})
</code></pre>
      <h3 id="t103.3 index.html">3.3 index.html <a href="#t103.3%20index.html"> # </a></h3>
      <p>index.html</p>
      <pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Vite App<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/src/main.ts"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
      <h3 id="t113.4 src\env.d.ts">3.4 src\env.d.ts <a href="#t113.4%20src\env.d.ts"> # </a></h3>
      <ul>
        <li>Vite 默认的类型定义是写给它的 Node.js API 的,要将其补充到一个 Vite 应用的客户端代码环境中</li>
        <li><a href="https://vitejs.cn/guide/features.html#typescript-compiler-options">客户端类型</a></li>
        <li>如果你的库依赖于某个全局库<ul>
            <li>使用<code>///</code> 指令</li>
            <li>三斜线指令仅可放在包含它的文件的最顶端</li>
            <li>三斜线引用告诉编译器在编译过程中要引入的额外的文件</li>
          </ul>
        </li>
      </ul>
      <pre><code class="lang-js"><span class="hljs-comment">/// &lt;reference types="vite/client" /&gt;</span>
</code></pre>
      <h3 id="t123.5 src\main.ts">3.5 src\main.ts <a href="#t123.5%20src\main.ts"> # </a></h3>
      <p>src\main.ts</p>
      <pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">render</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"app"</span>)!.innerHTML = <span class="hljs-string">"main"</span>;
}
render();

<span class="hljs-keyword">if</span> (<span class="hljs-keyword">import</span>.meta.hot) {
  <span class="hljs-keyword">import</span>.meta.hot.accept(<span class="hljs-function">(<span class="hljs-params">updatedModule</span>) =&gt;</span> updatedModule.render());
}

</code></pre>
      <h3 id="t133.6 tsconfig.json">3.6 tsconfig.json <a href="#t133.6%20tsconfig.json"> # </a></h3>
      <p>tsconfig.json</p>
      <pre><code class="lang-json">{
  <span class="hljs-attr">"compilerOptions"</span>: {
    <span class="hljs-attr">"target"</span>: <span class="hljs-string">"esnext"</span>,
    <span class="hljs-attr">"module"</span>: <span class="hljs-string">"esnext"</span>,
    <span class="hljs-attr">"moduleResolution"</span>: <span class="hljs-string">"node"</span>,
    <span class="hljs-attr">"strict"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"jsx"</span>: <span class="hljs-string">"preserve"</span>,
    <span class="hljs-attr">"sourceMap"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"esModuleInterop"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"lib"</span>: [<span class="hljs-string">"esnext"</span>, <span class="hljs-string">"dom"</span>, <span class="hljs-string">"es2018.promise"</span>]
  },
  <span class="hljs-attr">"include"</span>: [<span class="hljs-string">"src/**/*.ts"</span>, <span class="hljs-string">"src/**/*.d.ts"</span>, <span class="hljs-string">"src/**/*.tsx"</span>, <span class="hljs-string">"src/**/*.vue"</span>]
}
</code></pre>
      <table>
        <thead>
          <tr>
            <th style="text-align:left">参数</th>
            <th style="text-align:left">解释</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td style="text-align:left">target</td>
            <td style="text-align:left">用于指定编译之后的版本目标</td>
          </tr>
          <tr>
            <td style="text-align:left">module</td>
            <td style="text-align:left">生成的模块形式：none、commonjs、amd、system、umd、es6、es2015 或 esnext 只有 amd 和 system 能和
              outFile 一起使用 target 为 es5 或更低时可用 es6 和 es2015</td>
          </tr>
          <tr>
            <td style="text-align:left">moduleResolution</td>
            <td style="text-align:left">选择模块解析策略，有 node 和 classic 两种类型 <a
                href="https://www.typescriptlang.org/docs/handbook/module-resolution.html">module-resolution</a></td>
          </tr>
          <tr>
            <td style="text-align:left">strict</td>
            <td style="text-align:left">是否启动所有类型检查</td>
          </tr>
          <tr>
            <td style="text-align:left">jsx</td>
            <td style="text-align:left">react 模式会生成 React.createElement，在使用前不需要再进行转换操作了，输出文件的扩展名为.js</td>
          </tr>
          <tr>
            <td style="text-align:left">sourceMap</td>
            <td style="text-align:left">把 ts 文件编译成 js 文件的时候，同时生成对应的 sourceMap 文件</td>
          </tr>
          <tr>
            <td style="text-align:left">esModuleInterop</td>
            <td style="text-align:left">为导入内容创建命名空间,实现 CommonJS 和 ES 模块之间的互相访问</td>
          </tr>
          <tr>
            <td style="text-align:left">lib</td>
            <td style="text-align:left">编译时引入的 ES 功能库，包括：es5 、es6、es7、dom 等。如果未设置，则默认为： target 为 es5 时: ["dom", "es5",
              "scripthost"] target 为 es6 时: ["dom", "es6", "dom.iterable", "scripthost"]</td>
          </tr>
          <tr>
            <td style="text-align:left">include</td>
            <td style="text-align:left">include 也可以指定要编译的路径列表，但是和 files 的区别在于，这里的路径可以是文件夹，也可以是文件</td>
          </tr>
        </tbody>
      </table>
      <h3 id="t143.7 .gitignore">3.7 .gitignore <a href="#t143.7%20.gitignore"> # </a></h3>
      <p>.gitignore</p>
      <pre><code class="lang-js">node_modules
pnpm-debug.log*
.vscode<span class="hljs-comment">/*
sh.exe.stackdump
dist
coverage
</span></code></pre>
      <h2 id="t154.支持 vue3">4.支持 vue3 <a href="#t154.%E6%94%AF%E6%8C%81%20vue3"> # </a></h2>
      <h3 id="t164.1 安装 vue">4.1 安装 vue <a href="#t164.1%20%E5%AE%89%E8%A3%85%20vue"> # </a></h3>
      <pre><code class="lang-js">pnpm install vue
pnpm install @vitejs/plugin-vue -D
</code></pre>
      <h3 id="t174.2 vite.config.ts">4.2 vite.config.ts <a href="#t174.2%20vite.config.ts"> # </a></h3>
      <p>vite.config.ts</p>
      <pre><code class="lang-diff">import { defineConfig } from 'vite'
<span class="hljs-addition">+import vue from "@vitejs/plugin-vue";</span>
export default defineConfig({
<span class="hljs-addition">+ plugins: [vue()]</span>
})
</code></pre>
      <h3 id="t184.3 src\env.d.ts">4.3 src\env.d.ts <a href="#t184.3%20src\env.d.ts"> # </a></h3>
      <p>src\env.d.ts</p>
      <pre><code class="lang-diff">/// &lt;reference types="vite/client" /&gt;
<span class="hljs-addition">+declare module "*.vue" {</span>
<span class="hljs-addition">+  import type { DefineComponent } from "vue";</span>
<span class="hljs-addition">+  const component: DefineComponent&lt;{}, {}, any&gt;;</span>
<span class="hljs-addition">+  export default component;</span>
<span class="hljs-addition">+}</span>
</code></pre>
      <h3 id="t194.4 src\main.ts">4.4 src\main.ts <a href="#t194.4%20src\main.ts"> # </a></h3>
      <p>src\main.ts</p>
      <pre><code class="lang-diff"><span class="hljs-addition">+import { createApp } from "vue";</span>
<span class="hljs-addition">+import App from "./App.vue";</span>
<span class="hljs-addition">+const app = createApp(App)</span>
<span class="hljs-addition">+app.mount("#app");</span>
</code></pre>
      <h3 id="t204.5 src\App.vue">4.5 src\App.vue <a href="#t204.5%20src\App.vue"> # </a></h3>
      <p>src\App.vue</p>
      <pre><code class="lang-js">&lt;script setup lang="ts"&gt;
import HelloWorld from './components/HelloWorld.vue'
&lt;/script&gt;

&lt;template&gt;
  &lt;HelloWorld msg="Vue3 + TypeScript + Vite2" /&gt;
&lt;/template&gt;

&lt;style&gt;&lt;/style&gt;
</code></pre>
      <h3 id="t214.6 HelloWorld.vue">4.6 HelloWorld.vue <a href="#t214.6%20HelloWorld.vue"> # </a></h3>
      <p>src\components\HelloWorld.vue</p>
      <ul>
        <li><a
            href="https://v3.cn.vuejs.org/api/sfc-script-setup.html#%E5%8D%95%E6%96%87%E4%BB%B6%E7%BB%84%E4%BB%B6-script-setup">单文件组件
            <code>&lt;script setup&gt;</code></a>是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖</li>
        <li><a href="https://v3.cn.vuejs.org/api/sfc-spec.html#%E9%A2%84%E5%A4%84%E7%90%86">lang</a>属性可以声明预处理语言</li>
        <li><a href="https://v3.cn.vuejs.org/api/refs-api.html#ref"><code>ref</code></a>接受一个内部值并返回一个响应式且可变的 ref 对象。ref
          对象仅有一个 <code>.value</code> 属性，指向该内部值,在 JS 中操作数据需要<code>.value</code>,在模板中读取不需要<code>.value</code></li>
        <li>在 <code>&lt;script setup&gt;</code> 中必须使用 <a
            href="https://v3.cn.vuejs.org/api/sfc-script-setup.html#defineprops-%E5%92%8C-defineemits">defineProps</a>
          API 来声明 props，只在 <code>&lt;script setup&gt;</code> 中才能使用的编译器宏。他们不需要导入且会随着 <code>&lt;script setup&gt;</code>
          处理过程一同被编译掉</li>
      </ul>
      <pre><code class="lang-js">&lt;script setup lang="ts"&gt;
import { ref } from 'vue'
import logoUrl from '../assets/logo.png'
defineProps&lt;{ msg: string }&gt;()
const count = ref(0)
&lt;/script&gt;

&lt;template&gt;
  &lt;h1&gt;{{ msg }}&lt;/h1&gt;
  &lt;img :src="logoUrl" /&gt;
  &lt;div&gt;
    &lt;button type="button" @click="count++"&gt;count is: {{ count }}&lt;/button&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;style scoped&gt;
img {
  width: 100px;
  height: 100px;
}
&lt;/style&gt;
</code></pre>
      <h2 id="t225.支持 typescript">5.支持 typescript <a href="#t225.%E6%94%AF%E6%8C%81%20typescript"> # </a>
      </h2>
      <ul>
        <li>只编译不校验</li>
      </ul>
      <h3 id="t235.1 安装">5.1 安装 <a href="#t235.1%20%E5%AE%89%E8%A3%85"> # </a></h3>
      <ul>
        <li><a href="https://www.npmjs.com/package/typescript">typescript</a>是一种基于 JavaScript 的强类型编程语言</li>
        <li><a href="https://www.npmjs.com/package/vue-tsc">vue-tsc</a>可以对 Vue3 进行 Typescript 类型较验</li>
      </ul>
      <pre><code class="lang-js">pnpm install typescript vue-tsc  -D
</code></pre>
      <h3 id="t245.2 package.json">5.2 package.json <a href="#t245.2%20package.json"> # </a></h3>
      <p>package.json</p>
      <pre><code class="lang-diff">{
  "scripts": {
    "dev": "vite",
<span class="hljs-addition">+   "build": "vue-tsc --noEmit &amp;&amp; vite build"</span>
  },
}
</code></pre>
      <h3 id="t255.3 msg.ts">5.3 msg.ts <a href="#t255.3%20msg.ts"> # </a></h3>
      <p>src\msg.ts</p>
      <pre><code class="lang-js">interface Msg {
  <span class="hljs-attr">text</span>: string;
}
<span class="hljs-keyword">const</span> msg: Msg = {
  <span class="hljs-attr">text</span>: <span class="hljs-string">"zhufeng"</span>,
  <span class="hljs-attr">age</span>: <span class="hljs-number">13</span>
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> msg
</code></pre>
      <h3 id="t265.4 App.vue">5.4 App.vue <a href="#t265.4%20App.vue"> # </a></h3>
      <p>src\App.vue</p>
      <pre><code class="lang-diff">&lt;script setup lang="ts"&gt;
import HelloWorld from './components/HelloWorld.vue'
<span class="hljs-addition">+import msg from "./msg"</span>
&lt;/script&gt;

&lt;template&gt;
<span class="hljs-addition">+  &lt;HelloWorld :msg="msg.text" /&gt;</span>
&lt;/template&gt;

&lt;style&gt;&lt;/style&gt;
</code></pre>
      <h2 id="t276.ESLint">6.ESLint <a href="#t276.ESLint"> #
        </a></h2>
      <ul>
        <li>ESLint<a href="https://eslint.bootcss.com/">eslint</a> 是一个插件化并且可配置的 JavaScript 语法规则和代码风格的检查工具<ul>
            <li>代码质量问题：使用方式有可能有问题</li>
            <li>代码风格问题：风格不符合一定规则</li>
          </ul>
        </li>
      </ul>
      <h3 id="t286.1 安装">6.1 安装 <a href="#t286.1%20%E5%AE%89%E8%A3%85"> # </a></h3>
      <pre><code class="lang-js">pnpm install eslint eslint-plugin-vue  @typescript-eslint/parser @typescript-eslint/eslint-plugin @vue/eslint-config-typescript   -D
</code></pre>
      <table>
        <thead>
          <tr>
            <th style="text-align:left">名称</th>
            <th style="text-align:left">说明</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td style="text-align:left">eslint</td>
            <td style="text-align:left">ESLint 是一个用于识别和报告在 ECMAScript/JavaScript 代码中发现的模式的工具</td>
          </tr>
          <tr>
            <td style="text-align:left">eslint-plugin-vue</td>
            <td style="text-align:left">Vue 的官方 ESLint 插件</td>
          </tr>
          <tr>
            <td style="text-align:left">@typescript-eslint/parser</td>
            <td style="text-align:left">一个 ESLint 解析器，它利用 TypeScript-ESTree 允许 ESLint 检查 TypeScript 源代码</td>
          </tr>
          <tr>
            <td style="text-align:left">@typescript-eslint/eslint-plugin</td>
            <td style="text-align:left">一个 ESLint 插件，为 TypeScript 代码库提供 lint 规则</td>
          </tr>
          <tr>
            <td style="text-align:left">@vue/eslint-config-typescript</td>
            <td style="text-align:left">Vue 的 eslint-config-typescript</td>
          </tr>
        </tbody>
      </table>
      <h3 id="t296.2 .eslintrc.js">6.2 .eslintrc.js <a href="#t296.2%20.eslintrc.js"> # </a></h3>
      <p>.eslintrc.js</p>
      <pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">root</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">env</span>: {
    <span class="hljs-attr">browser</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">es2021</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">node</span>: <span class="hljs-literal">true</span>
  },

  <span class="hljs-attr">extends</span>: [
    <span class="hljs-string">"plugin:vue/vue3-recommended"</span>,
    <span class="hljs-string">"eslint:recommended"</span>,
    <span class="hljs-string">"@vue/typescript/recommended"</span>
  ],
  <span class="hljs-attr">parserOptions</span>: {
    <span class="hljs-attr">parser</span>: <span class="hljs-string">"@typescript-eslint/parser"</span>,
    <span class="hljs-attr">ecmaVersion</span>: <span class="hljs-number">2021</span>
  },
  <span class="hljs-attr">rules</span>: {
    <span class="hljs-string">"no-unused-vars"</span>: <span class="hljs-string">"off"</span>,
    <span class="hljs-string">"vue/no-unused-vars"</span>: <span class="hljs-string">"off"</span>,
    <span class="hljs-string">"@typescript-eslint/no-unused-vars"</span>: <span class="hljs-string">"off"</span>
  },
  <span class="hljs-attr">globals</span>: {
    <span class="hljs-attr">defineProps</span>: <span class="hljs-string">"readonly"</span>
  }
}
</code></pre>
      <h3 id="t306.3 .eslintignore">6.3 .eslintignore <a href="#t306.3%20.eslintignore"> # </a></h3>
      <p>.eslintignore</p>
      <pre><code class="lang-js">node_modules
dist
*.css
*.jpg
*.jpeg
*.png
*.gif
*.d.ts
</code></pre>
      <h3 id="t316.4 package.json">6.4 package.json <a href="#t316.4%20package.json"> # </a></h3>
      <p>package.json</p>
      <pre><code class="lang-diff">{
    "scripts": {
     "dev": "vite",
     "build": "vue-tsc --noEmit &amp;&amp; vite build",
<span class="hljs-addition">+    "lint": "eslint --ext .ts,.tsx,vue src/** --no-error-on-unmatched-pattern --quiet",</span>
<span class="hljs-addition">+    "lint:fix": "eslint --ext .ts,.tsx,vue src/** --no-error-on-unmatched-pattern --quiet --fix"</span>
  },
}
</code></pre>
      <h2 id="t327.Prettier">7.Prettier <a href="#t327.Prettier"> # </a></h2>
      <ul>
        <li>ESLint 主要解决的是代码质量问题</li>
        <li><a href="https://eslint.bootcss.com/docs/rules/">代码质量规则</a>
          <ul>
            <li>no-unused-vars 禁止出现未使用过的变量</li>
            <li>no-implicit-globals 禁止在全局范围内使用变量声明和 function 声明</li>
            <li>prefer-promise-reject-errors 要求使用 Error 对象作为 Promise 拒绝的原因</li>
          </ul>
        </li>
        <li><a href="https://prettier.io/">prettier</a>主要解决的是代码风格问题<ul>
            <li>max-len 最大长度</li>
            <li>no-mixed-spaces-and-tabs 不允许空格和 tab 混合</li>
            <li>keyword-spacing 关键字的空</li>
            <li>comma-style 冒号风格</li>
          </ul>
        </li>
      </ul>
      <h3 id="t337.1 安装">7.1 安装 <a href="#t337.1%20%E5%AE%89%E8%A3%85"> # </a></h3>
      <pre><code class="lang-js">pnpm install prettier eslint-plugin-prettier  @vue/eslint-config-prettier -D
</code></pre>
      <table>
        <thead>
          <tr>
            <th style="text-align:left">名称</th>
            <th style="text-align:left">说明</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td style="text-align:left">prettier</td>
            <td style="text-align:left">代码格式化</td>
          </tr>
          <tr>
            <td style="text-align:left">eslint-plugin-prettier</td>
            <td style="text-align:left">作为 ESLint 规则运行得 prettier</td>
          </tr>
          <tr>
            <td style="text-align:left">@vue/eslint-config-prettier</td>
            <td style="text-align:left">Vue 的 eslint-config-prettier</td>
          </tr>
        </tbody>
      </table>
      <h3 id="t347.2 .eslintrc.js">7.2 .eslintrc.js <a href="#t347.2%20.eslintrc.js"> # </a></h3>
      <p>.eslintrc.js</p>
      <pre><code class="lang-diff">module.exports = {
  root: true,
  env: {
    browser: true,
    es2021: true,
    node: true
  },

  extends: [
    "plugin:vue/vue3-recommended",
    "eslint:recommended",
    "@vue/typescript/recommended",
<span class="hljs-addition">+   "prettier",</span>
<span class="hljs-addition">+   "@vue/eslint-config-prettier"</span>
  ],
  parserOptions: {
    parser: "@typescript-eslint/parser",
    ecmaVersion: 2021
  },
  rules: {
<span class="hljs-addition">+   "prettier/prettier": [</span>
<span class="hljs-addition">+     "error",</span>
<span class="hljs-addition">+     {</span>
<span class="hljs-addition">+       singleQuote: false,</span>
<span class="hljs-addition">+       tabWidth: 2,</span>
<span class="hljs-addition">+       indent: 2,</span>
<span class="hljs-addition">+       semi: false,</span>
<span class="hljs-addition">+       trailingComma: "none",</span>
<span class="hljs-addition">+       endOfLine: "auto"</span>
<span class="hljs-addition">+     }</span>
<span class="hljs-addition">+   ],</span>
<span class="hljs-addition">+   "no-unused-vars": "off",</span>
<span class="hljs-addition">+   "vue/no-unused-vars": "off",</span>
<span class="hljs-addition">+   "@typescript-eslint/no-unused-vars": "off"</span>
<span class="hljs-addition">+ },</span>
  globals: {
    defineProps: "readonly"
  }
}

</code></pre>
      <h3 id="t357.3 .prettierrc.js">7.3 .prettierrc.js <a href="#t357.3%20.prettierrc.js"> # </a></h3>
      <p>.prettierrc.js</p>
      <pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">singleQuote</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">//使用单引号</span>
  <span class="hljs-attr">semi</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">////末尾添加分号</span>
  <span class="hljs-attr">tabWidth</span>: <span class="hljs-number">2</span>,
  <span class="hljs-attr">trailingComma</span>: <span class="hljs-string">"none"</span>,
  <span class="hljs-attr">useTabs</span>: <span class="hljs-literal">false</span>,
  <span class="hljs-attr">endOfLine</span>: <span class="hljs-string">"auto"</span>
}
</code></pre>
      <h3 id="t367.4 .prettierignore">7.4 .prettierignore <a href="#t367.4%20.prettierignore"> # </a></h3>
      <p>.prettierignore</p>
      <pre><code class="lang-js">node_modules
dist
</code></pre>
      <h3 id="t377.5 editorconfig">7.5 editorconfig <a href="#t377.5%20editorconfig"> # </a></h3>
      <ul>
        <li><a href="https://editorconfig.org/">editorconfig</a>帮助开发人员在不同的编辑器和 IDE 之间定义和维护一致的编码样式</li>
        <li>不同的开发人员，不同的编辑器，有不同的编码风格，而 EditorConfig 就是用来协同团队开发人员之间的代码的风格及样式规范化的一个工具，而.editorconfig 正是它的默认配置文件</li>
        <li><a href="https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig">EditorConfig</a>
        </li>
        <li>vscode 这类编辑器，需要自行安装 editorconfig 插件</li>
      </ul>
      <h4 id="t387.5.1 .editorconfig">7.5.1 .editorconfig <a href="#t387.5.1%20.editorconfig"> # </a></h4>
      <ul>
        <li>Unix 系统里，每行结尾只有换行,即<code>\n</code> LF(Line Feed)</li>
        <li>Windows 系统里面，每行结尾是<code>换行 回车</code>，即<code>\r\n</code> CR/LF</li>
        <li>Mac 系统里，每行结尾是<code>回车</code>，即<code>\r</code> CR(Carriage Return)</li>
      </ul>
      <pre><code class="lang-js">root = <span class="hljs-literal">true</span>

[*]
charset = utf<span class="hljs-number">-8</span>
indent_style = space
indent_size = <span class="hljs-number">2</span>
end_of_line = lf
</code></pre>
      <h3 id="t397.6 自动格式化">7.6 自动格式化 <a href="#t397.6%20%E8%87%AA%E5%8A%A8%E6%A0%BC%E5%BC%8F%E5%8C%96">
          # </a></h3>
      <p><img src="./typescript6/formatonsave_1645855381499.png" alt=""></p>
      <p><img src="./typescript6/formatter_1645855386534.png" alt=""></p>
      <h2 id="t408.git hooks">8.git hooks <a href="#t408.git%20hooks"> # </a></h2>
      <ul>
        <li>可以在<code>git commit</code>之前检查代码，保证所有提交到版本库中的代码都是符合规范的</li>
        <li>可以在<code>git push</code>之前执行单元测试,保证所有的提交的代码经过的单元测试</li>
        <li><a href="https://typicode.github.io/husky">husky</a>可以让我们向项目中方便添加<code>git hooks</code>,它会自动在仓库中的
          <code>.git/</code> 目录下增加相应的钩子,比如 <code>pre-commit</code> 钩子就会在你执行 <code>git commit</code>命令的时候的触发</li>
        <li><a href="https://www.npmjs.com/package/lint-staged">lint-staged</a>用于实现每次提交只检查本次提交所修改的文件</li>
        <li><a href="https://www.npmjs.com/package/mrm">mrm</a>可以根据<code>package.json</code>依赖项中的代码质量工具来安装和配置
          <code>husky</code> 和 <code>lint-staged</code></li>
        <li>Commitlint 可以规范<code>git commit -m ""</code>中的描述信息</li>
      </ul>
      <h3 id="t418.1 lint-staged">8.1 lint-staged <a href="#t418.1%20lint-staged"> # </a></h3>
      <h4 id="t428.1.1 安装">8.1.1 安装 <a href="#t428.1.1%20%E5%AE%89%E8%A3%85"> # </a></h4>
      <ul>
        <li><code>mrm</code>安装<code>lint-staged</code>的同时会安装<code>husky</code></li>
      </ul>
      <pre><code class="lang-js">pnpm install mrm  -D
npx mrm lint-staged
</code></pre>
      <h4 id="t438.1.2 package.json">8.1.2 package.json <a href="#t438.1.2%20package.json"> # </a></h4>
      <p>package.json</p>
      <pre><code class="lang-diff">{
  "name": "vite2vue3ts-prepare",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit &amp;&amp; vite build",
    "lint": "eslint --ext .ts,vue src/** --no-error-on-unmatched-pattern --quiet",
    "lint:fix": "eslint --ext .ts,vue src/** --no-error-on-unmatched-pattern --fix",
<span class="hljs-addition">+   "prepare": "husky install"</span>
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "vue": "^3.2.31"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^5.12.1",
    "@typescript-eslint/parser": "^5.12.1",
    "@vitejs/plugin-vue": "^2.2.2",
    "@vue/eslint-config-prettier": "^7.0.0",
    "@vue/eslint-config-typescript": "^10.0.0",
    "eslint": "^8.10.0",
    "eslint-plugin-prettier": "^4.0.0",
    "eslint-plugin-vue": "^8.5.0",
<span class="hljs-addition">+   "husky": "^7.0.0",</span>
<span class="hljs-addition">+   "lint-staged": "^12.3.4",</span>
<span class="hljs-addition">+   "mrm": "^3.0.10",</span>
    "prettier": "^2.5.1",
    "typescript": "^4.5.5",
    "vite": "^2.8.4",
    "vue-tsc": "^0.32.0"
  },
<span class="hljs-addition">+ "lint-staged": {</span>
<span class="hljs-addition">+   "*.{ts,vue}": "eslint --cache --fix"</span>
<span class="hljs-addition">+ }</span>
}
</code></pre>
      <h3 id="t448.2 commitlint">8.2 commitlint <a href="#t448.2%20commitlint"> # </a></h3>
      <ul>
        <li><a href="https://www.npmjs.com/package/@commitlint/cli">commitlint</a>推荐我们使用<a
            href="https://www.npmjs.com/package/@commitlint/config-conventional">onfig-conventional</a>配置去写
          <code>commit</code></li>
        <li>提交格式 <code>git commit -m &lt;type&gt;[optional scope]: &lt;description&gt;</code>
          <ul>
            <li><code>type</code> ：用于表明我们这次提交的改动类型，是新增了功能？还是修改了测试代码？又或者是更新了文档？</li>
            <li><code>optional scope</code>：一个可选的修改范围。用于标识此次提交主要涉及到代码中哪个模块</li>
            <li><code>description</code>：一句话描述此次提交的主要内容，做到言简意赅</li>
          </ul>
        </li>
      </ul>
      <h4 id="t458.2.1 type">8.2.1 type <a href="#t458.2.1%20type"> # </a></h4>
      <table>
        <thead>
          <tr>
            <th style="text-align:left">类型</th>
            <th style="text-align:left">描述</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td style="text-align:left">build</td>
            <td style="text-align:left">编译相关的修改，例如发布版本、对项目构建或者依赖的改动</td>
          </tr>
          <tr>
            <td style="text-align:left">chore</td>
            <td style="text-align:left">其他修改, 比如改变构建流程、或者增加依赖库、工具等</td>
          </tr>
          <tr>
            <td style="text-align:left">ci</td>
            <td style="text-align:left">持续集成修改</td>
          </tr>
          <tr>
            <td style="text-align:left">docs</td>
            <td style="text-align:left">文档修改</td>
          </tr>
          <tr>
            <td style="text-align:left">feature</td>
            <td style="text-align:left">新特性、新功能</td>
          </tr>
          <tr>
            <td style="text-align:left">fix</td>
            <td style="text-align:left">修改 bug</td>
          </tr>
          <tr>
            <td style="text-align:left">perf</td>
            <td style="text-align:left">优化相关，比如提升性能、体验</td>
          </tr>
          <tr>
            <td style="text-align:left">refactor</td>
            <td style="text-align:left">代码重构</td>
          </tr>
          <tr>
            <td style="text-align:left">revert</td>
            <td style="text-align:left">回滚到上一个版本</td>
          </tr>
          <tr>
            <td style="text-align:left">style</td>
            <td style="text-align:left">代码格式修改</td>
          </tr>
          <tr>
            <td style="text-align:left">test</td>
            <td style="text-align:left">测试用例修改</td>
          </tr>
        </tbody>
      </table>
      <h4 id="t468.2.2 安装">8.2.2 安装 <a href="#t468.2.2%20%E5%AE%89%E8%A3%85"> # </a></h4>
      <pre><code class="lang-js">pnpm install @commitlint/cli @commitlint/config-conventional -D
</code></pre>
      <h4 id="t478.2.3 配置">8.2.3 配置 <a href="#t478.2.3%20%E9%85%8D%E7%BD%AE"> # </a></h4>
      <pre><code class="lang-js">npx husky add .husky/commit-msg <span class="hljs-string">"npx --no-install commitlint --edit $1"</span>
</code></pre>
      <h4 id="t488.2.4 commitlint.config.js">8.2.4 commitlint.config.js <a href="#t488.2.4%20commitlint.config.js"> #
        </a></h4>
      <pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">extends</span>: [<span class="hljs-string">"@commitlint/config-conventional"</span>],
  <span class="hljs-attr">rules</span>: {
    <span class="hljs-string">"type-enum"</span>: [
      <span class="hljs-number">2</span>,
      <span class="hljs-string">"always"</span>,
      [
        <span class="hljs-string">"build"</span>,
        <span class="hljs-string">"chore"</span>,
        <span class="hljs-string">"ci"</span>,
        <span class="hljs-string">"docs"</span>,
        <span class="hljs-string">"feature"</span>,
        <span class="hljs-string">"fix"</span>,
        <span class="hljs-string">"perf"</span>,
        <span class="hljs-string">"refactor"</span>,
        <span class="hljs-string">"revert"</span>,
        <span class="hljs-string">"style"</span>,
        <span class="hljs-string">"test"</span>
      ]
    ]
  }
}
</code></pre>
      <h2 id="t499.配置别名">9.配置别名 <a href="#t499.%E9%85%8D%E7%BD%AE%E5%88%AB%E5%90%8D"> #
        </a></h2>
      <h3 id="t509.1 vite.config.ts">9.1 vite.config.ts <a href="#t509.1%20vite.config.ts"> # </a></h3>
      <pre><code class="lang-diff">import { defineConfig } from "vite"
<span class="hljs-addition">+import { resolve } from "path"</span>
import vue from "@vitejs/plugin-vue"
export default defineConfig({
<span class="hljs-addition">+ resolve: {</span>
<span class="hljs-addition">+   alias: {</span>
<span class="hljs-addition">+     "@": resolve("src")</span>
<span class="hljs-addition">+   }</span>
<span class="hljs-addition">+ },</span>
  plugins: [vue()]
})

</code></pre>
      <h3 id="t519.2 tsconfig.json">9.2 tsconfig.json <a href="#t519.2%20tsconfig.json"> # </a></h3>
      <p>tsconfig.json</p>
      <pre><code class="lang-diff">{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "esModuleInterop": true,
    "lib": ["esnext", "dom", "es2018.promise"],
<span class="hljs-addition">+   "baseUrl": ".",</span>
<span class="hljs-addition">+   "paths": {</span>
<span class="hljs-addition">+     "@/*": ["src/*"]</span>
<span class="hljs-addition">+   }</span>
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}
</code></pre>
      <h3 id="t529.3 App.vue">9.3 App.vue <a href="#t529.3%20App.vue"> # </a></h3>
      <p>src\App.vue</p>
      <pre><code class="lang-diff">&lt;script setup lang="ts"&gt;
<span class="hljs-addition">+import HelloWorld from "@/components/HelloWorld.vue"</span>
import msg from "./msg"
&lt;/script&gt;

&lt;template&gt;
  &lt;HelloWorld :msg="msg.text" /&gt;
&lt;/template&gt;

&lt;style&gt;&lt;/style&gt;

</code></pre>
      <h2 id="t5310.样式处理">10.样式处理 <a href="#t5310.%E6%A0%B7%E5%BC%8F%E5%A4%84%E7%90%86"> #
        </a></h2>
      <h3 id="t5410.1 全局样式">10.1 全局样式 <a href="#t5410.1%20%E5%85%A8%E5%B1%80%E6%A0%B7%E5%BC%8F">
          # </a></h3>
      <h4 id="t5510.1.1 src\global.css">10.1.1 src\global.css <a href="#t5510.1.1%20src\global.css"> # </a></h4>
      <pre><code class="lang-css"><span class="hljs-selector-id">#app</span> {
  <span class="hljs-attribute">background-color</span>: lightgrey;
}
</code></pre>
      <h4 id="t5610.1.2 src\main.ts">10.1.2 src\main.ts <a href="#t5610.1.2%20src\main.ts"> # </a></h4>
      <p>src\main.ts</p>
      <pre><code class="lang-diff">import { createApp } from "vue"
import App from "./App.vue"
<span class="hljs-addition">+import "./global.css"</span>
const app = createApp(App)
app.mount("#app")
</code></pre>
      <h3 id="t5710.2 局部样式">10.2 局部样式 <a href="#t5710.2%20%E5%B1%80%E9%83%A8%E6%A0%B7%E5%BC%8F">
          # </a></h3>
      <ul>
        <li>当 <code>style</code>标签有 <code>scoped</code> 属性时，它的 <code>CSS</code> 只作用于当前组件中的元素</li>
        <li>它使用了 <code>data-v-hash</code> 的方式来使 css 有了它对应模块的标识</li>
      </ul>
      <h4 id="t5810.2.1 HelloWorld.vue">10.2.1 HelloWorld.vue <a href="#t5810.2.1%20HelloWorld.vue"> # </a></h4>
      <p>src\components\HelloWorld.vue</p>
      <pre><code class="lang-diff">&lt;script setup lang="ts"&gt;
import { ref } from "vue"
import logoUrl from "../assets/logo.png"
defineProps&lt;{ msg: string }&gt;()
const count = ref(0)
&lt;/script&gt;

&lt;template&gt;
  &lt;h1&gt;{{ msg }}&lt;/h1&gt;
  &lt;img :src="logoUrl" /&gt;
  &lt;div&gt;
    &lt;button type="button" @click="count++"&gt;count is: {{ count }}&lt;/button&gt;
  &lt;/div&gt;
<span class="hljs-addition">+ &lt;a&gt;超链接&lt;/a&gt;</span>
&lt;/template&gt;

&lt;style scoped&gt;
img {
  width: 100px;
  height: 100px;
}
<span class="hljs-addition">+a {</span>
<span class="hljs-addition">+  color: red;</span>
<span class="hljs-addition">+}</span>
&lt;/style&gt;

</code></pre>
      <h3 id="t5910.3 CSS Modules">10.3 CSS Modules <a href="#t5910.3%20CSS%20Modules"> # </a></h3>
      <ul>
        <li>通过 <code>module</code> 作用的 <code>style</code> 都被保存到<code>$style</code> 对象中</li>
      </ul>
      <h4 id="t6010.3.1 内联">10.3.1 内联 <a href="#t6010.3.1%20%E5%86%85%E8%81%94"> # </a></h4>
      <h5 id="t6110.3.1.1 HelloWorld.vue">10.3.1.1 HelloWorld.vue <a href="#t6110.3.1.1%20HelloWorld.vue"> # </a></h5>
      <p>src\components\HelloWorld.vue</p>
      <pre><code class="lang-diff">&lt;script setup lang="ts"&gt;
import { ref } from "vue"
import logoUrl from "../assets/logo.png"
defineProps&lt;{ msg: string }&gt;()
const count = ref(0)
&lt;/script&gt;

&lt;template&gt;
  &lt;h1&gt;{{ msg }}&lt;/h1&gt;
  &lt;img :src="logoUrl" /&gt;
  &lt;div&gt;
    &lt;button type="button" @click="count++"&gt;count is: {{ count }}&lt;/button&gt;
  &lt;/div&gt;
<span class="hljs-addition">+ &lt;a :class="$style.link"&gt;超链接&lt;/a&gt;</span>
&lt;/template&gt;

&lt;style scoped&gt;
img {
  width: 100px;
  height: 100px;
}
&lt;/style&gt;
<span class="hljs-addition">+&lt;style module&gt;</span>
<span class="hljs-addition">+.link {</span>
<span class="hljs-addition">+  color: red;</span>
<span class="hljs-addition">+}</span>
<span class="hljs-addition">+&lt;/style&gt;</span>


</code></pre>
      <h4 id="t6210.3.2 外联">10.3.2 外联 <a href="#t6210.3.2%20%E5%A4%96%E8%81%94"> # </a></h4>
      <ul>
        <li>任何以 <code>.module.css</code> 为后缀名的 CSS 文件都被认为是一个 <code>CSS modules</code> 文件</li>
        <li>导入这样的文件会返回一个相应的模块对象</li>
      </ul>
      <h5 id="t6310.3.2.1 HelloWorld.module.css">10.3.2.1 HelloWorld.module.css <a
          href="#t6310.3.2.1%20HelloWorld.module.css"> # </a>
      </h5>
      <p>src\components\HelloWorld.module.css</p>
      <pre><code class="lang-js">.link {
    <span class="hljs-attr">color</span>: red;
}
</code></pre>
      <h5 id="t6410.3.2.2 HelloWorld.vue">10.3.2.2 HelloWorld.vue <a href="#t6410.3.2.2%20HelloWorld.vue"> # </a></h5>
      <p>src\components\HelloWorld.vue</p>
      <pre><code class="lang-diff">&lt;script setup lang="ts"&gt;
import { ref } from "vue"
import logoUrl from "../assets/logo.png"
<span class="hljs-addition">+import style from "./HelloWorld.module.css"</span>
defineProps&lt;{ msg: string }&gt;()
const count = ref(0)
&lt;/script&gt;

&lt;template&gt;
  &lt;h1&gt;{{ msg }}&lt;/h1&gt;
  &lt;img :src="logoUrl" /&gt;
  &lt;div&gt;
    &lt;button type="button" @click="count++"&gt;count is: {{ count }}&lt;/button&gt;
  &lt;/div&gt;
<span class="hljs-addition">+ &lt;a :class="style.link"&gt;超链接&lt;/a&gt;</span>
&lt;/template&gt;

&lt;style scoped&gt;
img {
  width: 100px;
  height: 100px;
}
&lt;/style&gt;
<span class="hljs-deletion">-&lt;style module&gt;</span>
<span class="hljs-deletion">-.link {</span>
<span class="hljs-deletion">-  color: red;</span>
<span class="hljs-deletion">-}</span>
<span class="hljs-deletion">-&lt;/style&gt;</span>

</code></pre>
      <h3 id="t6510.4 预处理器">10.4 预处理器 <a href="#t6510.4%20%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8">
          # </a></h3>
      <ul>
        <li>Vite 也同时提供了对<a href="https://cn.vitejs.dev/guide/features.html#css-pre-processors">.scss, .sass, .less,
            .styl 和 stylus</a>文件的内置支持</li>
        <li>没有必要为它们安装特定的 Vite 插件，但必须安装相应的预处理器依赖</li>
        <li><code>Vite</code>为<code>Sass</code>和<code>Less</code>改进了<code>@import</code>解析，以保证<code>Vite</code>别名也能被使用
        </li>
      </ul>
      <h4 id="t6610.4.1 安装">10.4.1 安装 <a href="#t6610.4.1%20%E5%AE%89%E8%A3%85"> # </a></h4>
      <pre><code class="lang-js">pnpm install sass less -D
</code></pre>
      <h4 id="t6710.4.2 src\components\HelloWorld.vue">10.4.2 src\components\HelloWorld.vue <a
          href="#t6710.4.2%20src\components\HelloWorld.vue"> #
        </a></h4>
      <p>src\components\HelloWorld.vue</p>
      <pre><code class="lang-diff">&lt;script setup lang="ts"&gt;
import { ref } from "vue"
import logoUrl from "../assets/logo.png"
import style from "./HelloWorld.module.css"
defineProps&lt;{ msg: string }&gt;()
const count = ref(0)
&lt;/script&gt;

&lt;template&gt;
  &lt;h1&gt;{{ msg }}&lt;/h1&gt;
  &lt;img :src="logoUrl" /&gt;
  &lt;div&gt;
    &lt;button type="button" @click="count++"&gt;count is: {{ count }}&lt;/button&gt;
  &lt;/div&gt;
  &lt;a :class="style.link"&gt;超链接&lt;/a&gt;
  &lt;h2&gt;less&lt;/h2&gt;
  &lt;h3&gt;sass&lt;/h3&gt;
&lt;/template&gt;

&lt;style scoped&gt;
img {
  width: 100px;
  height: 100px;
}
&lt;/style&gt;
&lt;style module&gt;
.link {
  color: red;
}
&lt;/style&gt;
<span class="hljs-addition">+&lt;style scoped lang="less"&gt;</span>
<span class="hljs-addition">+@color: red;</span>
<span class="hljs-addition">+h2 {</span>
<span class="hljs-addition">+  color: @color;</span>
<span class="hljs-addition">+}</span>
<span class="hljs-addition">+&lt;/style&gt;</span>
<span class="hljs-addition">+&lt;style scoped lang="scss"&gt;</span>
<span class="hljs-addition">+$color: green;</span>
<span class="hljs-addition">+h3 {</span>
<span class="hljs-addition">+  color: $color;</span>
<span class="hljs-addition">+}</span>
<span class="hljs-addition">+&lt;/style&gt;</span>
</code></pre>
      <h3 id="t6810.5 全局注入">10.5 全局注入 <a href="#t6810.5%20%E5%85%A8%E5%B1%80%E6%B3%A8%E5%85%A5">
          # </a></h3>
      <ul>
        <li>可以把全局样式文件全局注入到项目中</li>
      </ul>
      <h4 id="t6910.5.1 vite.config.ts">10.5.1 vite.config.ts <a href="#t6910.5.1%20vite.config.ts"> # </a></h4>
      <p>vite.config.ts</p>
      <pre><code class="lang-diff">import { defineConfig } from "vite"
import { resolve } from "path"
import vue from "@vitejs/plugin-vue"
export default defineConfig({
  resolve: {
    alias: {
      "@": resolve("src")
    }
  },
  plugins: [vue()],
<span class="hljs-addition">+ css: {</span>
<span class="hljs-addition">+   preprocessorOptions: {</span>
<span class="hljs-addition">+     scss: {</span>
<span class="hljs-addition">+       additionalData: '@import "@/styles/theme.scss";'</span>
<span class="hljs-addition">+     },</span>
<span class="hljs-addition">+     less: {</span>
<span class="hljs-addition">+       additionalData: '@import "@/styles/theme.less";'</span>
<span class="hljs-addition">+     }</span>
<span class="hljs-addition">+   }</span>
<span class="hljs-addition">+ }</span>
})

</code></pre>
      <h4 id="t7010.5.2 src\styles\theme.less">10.5.2 src\styles\theme.less <a
          href="#t7010.5.2%20src\styles\theme.less"> # </a></h4>
      <p>src\styles\theme.less</p>
      <pre><code class="lang-diff">@color: red;
</code></pre>
      <h4 id="t7110.5.3 src\styles\theme.scss">10.5.3 src\styles\theme.scss <a
          href="#t7110.5.3%20src\styles\theme.scss"> # </a></h4>
      <p>src\styles\theme.scss</p>
      <pre><code class="lang-diff">$color: green;
</code></pre>
      <h4 id="t7210.5.4 src\components\HelloWorld.vue">10.5.4 src\components\HelloWorld.vue <a
          href="#t7210.5.4%20src\components\HelloWorld.vue"> #
        </a></h4>
      <p>src\components\HelloWorld.vue</p>
      <pre><code class="lang-diff">&lt;script setup lang="ts"&gt;
import { ref } from "vue"
import logoUrl from "../assets/logo.png"
import style from "./HelloWorld.module.css"
defineProps&lt;{ msg: string }&gt;()
const count = ref(0)
&lt;/script&gt;

&lt;template&gt;
  &lt;h1&gt;{{ msg }}&lt;/h1&gt;
  &lt;img :src="logoUrl" /&gt;
  &lt;div&gt;
    &lt;button type="button" @click="count++"&gt;count is: {{ count }}&lt;/button&gt;
  &lt;/div&gt;
  &lt;a :class="style.link"&gt;超链接&lt;/a&gt;
  &lt;h2&gt;less&lt;/h2&gt;
  &lt;h3&gt;sass&lt;/h3&gt;
&lt;/template&gt;

&lt;style scoped&gt;
img {
  width: 100px;
  height: 100px;
}
&lt;/style&gt;
&lt;style module&gt;
.link {
  color: red;
}
&lt;/style&gt;
&lt;style scoped lang="less"&gt;
<span class="hljs-deletion">-@color: red;</span>
h2 {
  color: @color;
}
&lt;/style&gt;
&lt;style scoped lang="scss"&gt;
<span class="hljs-deletion">-$color: green;</span>
h3 {
  color: $color;
}
&lt;/style&gt;


</code></pre>
      <h3 id="t7310.6 PostCSS">10.6 PostCSS <a href="#t7310.6%20PostCSS"> # </a></h3>
      <ul>
        <li>为了浏览器的兼容性，有时候我们必须加入-webkit,-ms,-o,-moz 这些前缀<ul>
            <li>Trident 内核：主要代表为 IE 浏览器, 前缀为-ms</li>
            <li>Gecko 内核：主要代表为 Firefox, 前缀为-moz</li>
            <li>Presto 内核：主要代表为 Opera, 前缀为-o</li>
            <li>Webkit 内核：产要代表为 Chrome 和 Safari, 前缀为-webkit</li>
          </ul>
        </li>
        <li>如果项目包含有效的 PostCSS 配置，它将会自动应用于所有已导入的 CSS</li>
      </ul>
      <h4 id="t7410.6.1 安装">10.6.1 安装 <a href="#t7410.6.1%20%E5%AE%89%E8%A3%85"> # </a></h4>
      <pre><code class="lang-js">pnpm install autoprefixer  -D
</code></pre>
      <h4 id="t7510.6.2 postcss.config.js">10.6.2 postcss.config.js <a href="#t7510.6.2%20postcss.config.js"> # </a>
      </h4>
      <p>postcss.config.js</p>
      <pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">plugins</span>: [<span class="hljs-built_in">require</span>(<span class="hljs-string">"autoprefixer"</span>)]
}
</code></pre>
      <h4 id="t7610.6.3 .browserslistrc">10.6.3 .browserslistrc <a href="#t7610.6.3%20.browserslistrc"> # </a></h4>
      <p>.browserslistrc</p>
      <pre><code class="lang-js">&gt;<span class="hljs-number">0.2</span>%
not dead
not op_mini all
</code></pre>
      <h4 id="t7710.6.4 HelloWorld.vue">10.6.4 HelloWorld.vue <a href="#t7710.6.4%20HelloWorld.vue"> # </a></h4>
      <p>src\components\HelloWorld.vue</p>
      <pre><code class="lang-diff">&lt;script setup lang="ts"&gt;
import { ref } from "vue"
import logoUrl from "../assets/logo.png"
import style from "./HelloWorld.module.css"
defineProps&lt;{ msg: string }&gt;()
const count = ref(0)
&lt;/script&gt;

&lt;template&gt;
  &lt;h1&gt;{{ msg }}&lt;/h1&gt;
  &lt;img :src="logoUrl" /&gt;
  &lt;div&gt;
    &lt;button type="button" @click="count++"&gt;count is: {{ count }}&lt;/button&gt;
  &lt;/div&gt;
  &lt;a :class="style.link"&gt;超链接&lt;/a&gt;
  &lt;h2&gt;less&lt;/h2&gt;
  &lt;h3&gt;sass&lt;/h3&gt;
<span class="hljs-addition">+ &lt;div class="postcss"&gt;&lt;/div&gt;</span>
&lt;/template&gt;

&lt;style scoped&gt;
img {
  width: 100px;
  height: 100px;
}
&lt;/style&gt;
&lt;style module&gt;
.link {
  color: red;
}
&lt;/style&gt;
&lt;style scoped lang="less"&gt;
@color: red;
h2 {
  color: @color;
}
&lt;/style&gt;
&lt;style scoped lang="scss"&gt;
$color: green;
h3 {
  color: $color;
}
&lt;/style&gt;
<span class="hljs-addition">+&lt;style scoped&gt;</span>
<span class="hljs-addition">+.postcss {</span>
<span class="hljs-addition">+  height: 30px;</span>
<span class="hljs-addition">+  width: 60px;</span>
<span class="hljs-addition">+  background-color: orange;</span>
<span class="hljs-addition">+  transform: rotate(25deg);</span>
<span class="hljs-addition">+}</span>
<span class="hljs-addition">+&lt;/style&gt;</span>
</code></pre>
      <h2 id="t7811.静态资源处理">11.静态资源处理 <a href="#t7811.%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E5%A4%84%E7%90%86">
          # </a></h2>
      <ul>
        <li><a href="https://cn.vitejs.dev/guide/assets.html">assets</a></li>
        <li>服务时引入一个静态资源会返回解析后的公共路径</li>
      </ul>
      <h3 id="t7911.1 模板引入">11.1 模板引入 <a href="#t7911.1%20%E6%A8%A1%E6%9D%BF%E5%BC%95%E5%85%A5">
          # </a></h3>
      <p>src\components\HelloWorld.vue</p>
      <pre><code class="lang-diff">&lt;template&gt;
<span class="hljs-addition">+ &lt;img src="@/assets/logo.png" style="width: 50px" /&gt;</span>
&lt;/template&gt;
</code></pre>
      <h3 id="t8011.2 JS 中引入">11.2 JS 中引入 <a href="#t8011.2%20JS%20%E4%B8%AD%E5%BC%95%E5%85%A5"> #
        </a></h3>
      <p>src\components\HelloWorld.vue</p>
      <pre><code class="lang-diff">&lt;script setup lang="ts"&gt;
<span class="hljs-addition">+import logoUrl from "@/assets/logo.png"</span>
&lt;/script&gt;
&lt;template&gt;
<span class="hljs-addition">+ &lt;img :src="logoUrl" style="width: 50px" /&gt;</span>
&lt;/template&gt;
</code></pre>
      <h3 id="t8111.3 CSS 引入">11.3 CSS 引入 <a href="#t8111.3%20CSS%20%E5%BC%95%E5%85%A5"> # </a>
      </h3>
      <p>src\components\HelloWorld.vue</p>
      <pre><code class="lang-diff">&lt;template&gt;
<span class="hljs-addition">+ &lt;div class="logo"&gt;&lt;/div&gt;</span>
&lt;/template&gt;
&lt;style scoped&gt;
.logo {
  width: 50px;
  height: 50px;
  background-image: url(@/assets/logo.png);
  background-size: contain;
}
&lt;/style&gt;
</code></pre>
      <h3 id="t8211.4 public 目录">11.4 public 目录 <a href="#t8211.4%20public%20%E7%9B%AE%E5%BD%95"> # </a>
      </h3>
      <ul>
        <li><a href="https://cn.vitejs.dev/guide/assets.html#the-public-directory">public 目录</a></li>
        <li>如果有以下需求<ul>
            <li>这些资源不会被源码引用（例如 robots.txt）</li>
            <li>这些资源必须保持原有文件名（没有经过 hash）</li>
            <li>那么你可以将该资源放在指定的 public 目录中，它应位于你的项目根目录</li>
            <li>该目录中的资源在开发时能直接通过 / 根路径访问到，并且打包时会被完整复制到目标目录的根目录下</li>
          </ul>
        </li>
      </ul>
      <p>index.html</p>
      <pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/logo.png"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"width:50px"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
      <h2 id="t8312. mock">12. mock <a href="#t8312.%20mock"> #
        </a></h2>
      <ul>
        <li><a
            href="https://github.com/vbenjs/vite-plugin-mock/blob/HEAD/README.zh_CN.md">vite-plugin-mock</a>提供本地和生产模拟服务
        </li>
        <li>vite 的数据模拟插件，是基于 vite.js 开发的。 并同时支持本地环境和生产环境</li>
      </ul>
      <h3 id="t8412.1 安装">12.1 安装 <a href="#t8412.1%20%E5%AE%89%E8%A3%85"> # </a></h3>
      <pre><code class="lang-js">pnpm install mockjs  vite-plugin-mock -D
</code></pre>
      <h3 id="t8512.2 vite.config.ts">12.2 vite.config.ts <a href="#t8512.2%20vite.config.ts"> # </a></h3>
      <p>vite.config.ts</p>
      <pre><code class="lang-diff">import { defineConfig } from "vite"
import { resolve } from "path"
import vue from "@vitejs/plugin-vue"
<span class="hljs-addition">+import { viteMockServe } from "vite-plugin-mock"</span>
export default defineConfig({
  resolve: {
    alias: {
      "@": resolve("src")
    }
  },
<span class="hljs-addition">+ plugins: [vue(), viteMockServe()],</span>
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: '@import "@/styles/theme.scss";'
      },
      less: {
        additionalData: '@import "@/styles/theme.less";'
      }
    }
  }
})

</code></pre>
      <h3 id="t8612.3 mock\auth.ts">12.3 mock\auth.ts <a href="#t8612.3%20mock\auth.ts"> # </a></h3>
      <p>mock\auth.ts</p>
      <pre><code class="lang-js"><span class="hljs-keyword">import</span> { MockMethod } <span class="hljs-keyword">from</span> <span class="hljs-string">"vite-plugin-mock"</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> [
  {
    <span class="hljs-attr">url</span>: <span class="hljs-string">"/api/currentUser"</span>,
    <span class="hljs-attr">method</span>: <span class="hljs-string">"get"</span>,
    <span class="hljs-attr">response</span>: <span class="hljs-function">(<span class="hljs-params">{ query }</span>) =&gt;</span> {
      <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">code</span>: <span class="hljs-number">0</span>,
        <span class="hljs-attr">data</span>: <span class="hljs-string">"zhufeng"</span>
      }
    }
  }
] <span class="hljs-keyword">as</span> MockMethod[]
</code></pre>
      <h2 id="t8713. 封装请求">13. 封装请求 <a href="#t8713.%20%E5%B0%81%E8%A3%85%E8%AF%B7%E6%B1%82">
          # </a></h2>
      <ul>
        <li><a href="https://www.attojs.com/">VueRequest</a></li>
      </ul>
      <h3 id="t8813.1 安装">13.1 安装 <a href="#t8813.1%20%E5%AE%89%E8%A3%85"> # </a></h3>
      <pre><code class="lang-js">pnpm install axios
</code></pre>
      <h3 id="t8913.2 mock\auth.ts">13.2 mock\auth.ts <a href="#t8913.2%20mock\auth.ts"> # </a></h3>
      <p>mock\auth.ts</p>
      <pre><code class="lang-diff">import { MockMethod } from "vite-plugin-mock"
export default [
<span class="hljs-addition">+ {</span>
<span class="hljs-addition">+   url: "/api/currentUser",</span>
<span class="hljs-addition">+   method: "get",</span>
<span class="hljs-addition">+   response: ({ headers }) =&gt; {</span>
<span class="hljs-addition">+     const { token } = headers</span>
<span class="hljs-addition">+     return {</span>
<span class="hljs-addition">+       code: 0,</span>
<span class="hljs-addition">+       data: token</span>
<span class="hljs-addition">+     }</span>
<span class="hljs-addition">+   }</span>
<span class="hljs-addition">+ },</span>
<span class="hljs-addition">+ {</span>
<span class="hljs-addition">+   url: "/api/login",</span>
<span class="hljs-addition">+   method: "post",</span>
<span class="hljs-addition">+   response: ({ body }) =&gt; {</span>
<span class="hljs-addition">+     //url body,query headers</span>
<span class="hljs-addition">+     return {</span>
<span class="hljs-addition">+       code: 0,</span>
<span class="hljs-addition">+       data: `${body.username}-token`</span>
<span class="hljs-addition">+     }</span>
<span class="hljs-addition">+   }</span>
<span class="hljs-addition">+ }</span>
] as MockMethod[]
</code></pre>
      <h3 id="t9013.3 http.ts">13.3 http.ts <a href="#t9013.3%20http.ts"> # </a></h3>
      <p>src\api\http.ts</p>
      <pre><code class="lang-js"><span class="hljs-keyword">import</span> axios, { AxiosRequestConfig } <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>
axios.defaults.baseURL = <span class="hljs-string">"/api"</span>
axios.defaults.timeout = <span class="hljs-number">10000</span>
axios.defaults.headers.post[<span class="hljs-string">"Content-Type"</span>] = <span class="hljs-string">"application/json;charset=UTF-8"</span>
axios.interceptors.request.use(
  (config): <span class="hljs-function"><span class="hljs-params">AxiosRequestConfig</span> =&gt;</span> {
    <span class="hljs-keyword">const</span> token = <span class="hljs-built_in">window</span>.sessionStorage.getItem(<span class="hljs-string">"token"</span>)
    <span class="hljs-keyword">if</span> (token) {
      ;(config.headers = config.headers || {}).token = token
    }
    <span class="hljs-keyword">return</span> config
  },
  (error) =&gt; {
    <span class="hljs-keyword">throw</span> error
  }
)
<span class="hljs-comment">// 响应拦截</span>
axios.interceptors.response.use(<span class="hljs-function">(<span class="hljs-params">res</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> res.data
})

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> axios
</code></pre>
      <h3 id="t9113.4 src\api\auth.ts">13.4 src\api\auth.ts <a href="#t9113.4%20src\api\auth.ts"> # </a></h3>
      <p>src\api\auth.ts</p>
      <pre><code class="lang-js"><span class="hljs-keyword">import</span> http <span class="hljs-keyword">from</span> <span class="hljs-string">"./http"</span>
<span class="hljs-keyword">import</span> { LoginParams } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/typings/auth"</span>
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">login</span>(<span class="hljs-params">loginParams: LoginParams</span>) </span>{
  <span class="hljs-keyword">return</span> http.post(<span class="hljs-string">"/login"</span>, loginParams)
}
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getCurrentUser</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> http.get(<span class="hljs-string">"/currentUser"</span>)
}
</code></pre>
      <h3 id="t9213.5 auth.ts">13.5 auth.ts <a href="#t9213.5%20auth.ts"> # </a></h3>
      <p>src\typings\auth.ts</p>
      <pre><code class="lang-js"><span class="hljs-keyword">export</span> interface LoginParams {
  <span class="hljs-attr">username</span>: string
  <span class="hljs-attr">password</span>: string
}
<span class="hljs-keyword">export</span> interface Response {
  <span class="hljs-attr">code</span>: number
  <span class="hljs-attr">data</span>: any
}
</code></pre>
      <h3 id="t9313.6 src\request.ts">13.6 src\request.ts <a href="#t9313.6%20src\request.ts"> # </a></h3>
      <p>src\request.ts</p>
      <pre><code class="lang-js"><span class="hljs-keyword">import</span> { LoginParams, Response } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/typings/auth"</span>
<span class="hljs-keyword">import</span> { login, getCurrentUser } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/api/auth"</span>
<span class="hljs-keyword">const</span> loginParams: LoginParams = { <span class="hljs-attr">username</span>: <span class="hljs-string">"zhufeng"</span>, <span class="hljs-attr">password</span>: <span class="hljs-string">"123456"</span> }
login(loginParams).then(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> token = result.data
  <span class="hljs-built_in">window</span>.sessionStorage.setItem(<span class="hljs-string">"token"</span>, token)
  getCurrentUser().then(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(result.data)
  })
})
</code></pre>
      <h3 id="t9413.7 main.ts">13.7 main.ts <a href="#t9413.7%20main.ts"> # </a></h3>
      <p>src\main.ts</p>
      <pre><code class="lang-diff">import { createApp } from "vue"
import App from "./App.vue"
import "./global.css"
<span class="hljs-addition">+import "@/request"</span>
const app = createApp(App)
app.mount("#app")


</code></pre>
      <h2 id="t9514. 状态管理">14. 状态管理 <a href="#t9514.%20%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86">
          # </a></h2>
      <ul>
        <li><a href="https://devtools.vuejs.org/">devtools</a></li>
        <li><a href="https://pinia.vuejs.org/introduction.html">pinia</a>
          <ul>
            <li>支持 Vue3</li>
            <li>抛弃 Mutations，只有 state、getters 和 actions</li>
          </ul>
        </li>
      </ul>
      <h3 id="t9614.1 安装">14.1 安装 <a href="#t9614.1%20%E5%AE%89%E8%A3%85"> # </a></h3>
      <pre><code class="lang-js">pnpm install pinia
</code></pre>
      <h3 id="t9714.2 src\main.ts">14.2 src\main.ts <a href="#t9714.2%20src\main.ts"> # </a></h3>
      <p>src\main.ts</p>
      <pre><code class="lang-diff">import { createApp } from "vue"
import App from "./App.vue"
import "./global.css"
import "@/request"
<span class="hljs-addition">+import { createPinia } from "pinia"</span>
const app = createApp(App)
<span class="hljs-addition">+app.use(createPinia())</span>
app.mount("#app")
</code></pre>
      <h3 id="t9814.3 store\index.ts">14.3 store\index.ts <a href="#t9814.3%20store\index.ts"> # </a></h3>
      <p>src\store\index.ts</p>
      <pre><code class="lang-js"><span class="hljs-keyword">import</span> { defineStore } <span class="hljs-keyword">from</span> <span class="hljs-string">"pinia"</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useMainStore = defineStore({
  <span class="hljs-attr">id</span>: <span class="hljs-string">"main"</span>,
  <span class="hljs-attr">state</span>: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> ({
    <span class="hljs-attr">count</span>: <span class="hljs-number">0</span>,
    <span class="hljs-attr">firstName</span>: <span class="hljs-string">"张"</span>,
    <span class="hljs-attr">lastName</span>: <span class="hljs-string">"三"</span>
  }),
  <span class="hljs-comment">//计算属性</span>
  <span class="hljs-attr">getters</span>: {
    <span class="hljs-attr">name</span>: <span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> state.firstName + state.lastName
  },
  <span class="hljs-attr">actions</span>: {
    <span class="hljs-keyword">async</span> addAmount(amount: number) {
      <span class="hljs-keyword">this</span>.count += amount
    }
  }
})
</code></pre>
      <h3 id="t9914.4 HelloWorld.vue">14.4 HelloWorld.vue <a href="#t9914.4%20HelloWorld.vue"> # </a></h3>
      <p>src\components\HelloWorld.vue</p>
      <pre><code class="lang-diff">&lt;script setup lang="ts"&gt;
import { ref } from "vue"
import logoUrl from "../assets/logo.png"
import style from "./HelloWorld.module.css"
<span class="hljs-addition">+import { useMainStore } from "@/store"</span>
<span class="hljs-addition">+import { storeToRefs } from "pinia"</span>
<span class="hljs-addition">+defineProps&lt;{ msg: string }&gt;()</span>
<span class="hljs-addition">+const count = ref(0)</span>
<span class="hljs-addition">+const mainStore = useMainStore()</span>
<span class="hljs-addition">+//const storeCount = mainStore.count</span>
<span class="hljs-addition">+const { count: storeCount } = storeToRefs(mainStore)</span>

<span class="hljs-addition">+const add = () =&gt; {</span>
<span class="hljs-addition">+  //适合多字段改变</span>
<span class="hljs-addition">+  mainStore.$patch({</span>
<span class="hljs-addition">+    name: "arch",</span>
<span class="hljs-addition">+    count: mainStore.count + 1</span>
<span class="hljs-addition">+  })</span>
<span class="hljs-addition">+}</span>
<span class="hljs-addition">+const add2 = () =&gt; {</span>
<span class="hljs-addition">+  //适合多字段改变</span>
<span class="hljs-addition">+  mainStore.$patch((state) =&gt; ({</span>
<span class="hljs-addition">+    name: "arch2",</span>
<span class="hljs-addition">+    count: mainStore.count + 2</span>
<span class="hljs-addition">+  }))</span>
<span class="hljs-addition">+}</span>
&lt;/script&gt;

&lt;template&gt;
  &lt;h1&gt;{{ msg }}&lt;/h1&gt;
  &lt;img :src="logoUrl" /&gt;
  &lt;div&gt;
    &lt;button type="button" @click="count++"&gt;count is: {{ count }}&lt;/button&gt;
  &lt;/div&gt;
  &lt;a :class="style.link"&gt;超链接&lt;/a&gt;
  &lt;h2&gt;less&lt;/h2&gt;
  &lt;h3&gt;sass&lt;/h3&gt;
  &lt;div class="postcss"&gt;&lt;/div&gt;
<span class="hljs-addition">+ &lt;div&gt;</span>
<span class="hljs-addition">+   &lt;p&gt;name:{{ mainStore.name }}&lt;/p&gt;</span>
<span class="hljs-addition">+   &lt;p&gt;count:{{ mainStore.count }}&lt;/p&gt;</span>
<span class="hljs-addition">+   &lt;p&gt;count:{{ storeCount }}&lt;/p&gt;</span>
<span class="hljs-addition">+   &lt;button @click="mainStore.count++"&gt;mainStore.count++&lt;/button&gt;</span>
<span class="hljs-addition">+   &lt;button @click="add()"&gt;add()&lt;/button&gt;</span>
<span class="hljs-addition">+   &lt;button @click="add2()"&gt;add2()&lt;/button&gt;</span>
<span class="hljs-addition">+   &lt;button @click="mainStore.addAmount(3)"&gt;mainStore.addAmount(3)&lt;/button&gt;</span>
<span class="hljs-addition">+   &lt;p&gt;name:{{ mainStore.name }}&lt;/p&gt;</span>
<span class="hljs-addition">+ &lt;/div&gt;</span>
&lt;/template&gt;

&lt;style scoped&gt;
img {
  width: 100px;
  height: 100px;
}
&lt;/style&gt;
&lt;style module&gt;
.link {
  color: red;
}
&lt;/style&gt;
&lt;style scoped lang="less"&gt;
@color: red;
h2 {
  color: @color;
}
&lt;/style&gt;
&lt;style scoped lang="scss"&gt;
$color: green;
h3 {
  color: $color;
}
&lt;/style&gt;
&lt;style scoped&gt;
.postcss {
  height: 30px;
  width: 60px;
  background-color: orange;
  transform: rotate(25deg);
}
&lt;/style&gt;


</code></pre>
      <h2 id="t10015. 路由">15. 路由 <a href="#t10015.%20%E8%B7%AF%E7%94%B1"> # </a></h2>
      <ul>
        <li><a href="https://next.router.vuejs.org/zh/guide/">router</a></li>
      </ul>
      <h3 id="t10115.1 安装">15.1 安装 <a href="#t10115.1%20%E5%AE%89%E8%A3%85"> # </a></h3>
      <pre><code class="lang-js">pnpm install vue-router
</code></pre>
      <h3 id="t10215.2 router\index.ts">15.2 router\index.ts <a href="#t10215.2%20router\index.ts"> # </a></h3>
      <p>src\router\index.ts</p>
      <pre><code class="lang-js"><span class="hljs-keyword">import</span> { createRouter, createWebHistory, RouteRecordRaw } <span class="hljs-keyword">from</span> <span class="hljs-string">"vue-router"</span>

<span class="hljs-keyword">const</span> routes: RouteRecordRaw[] = [
  {
    <span class="hljs-attr">path</span>: <span class="hljs-string">"/"</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">"home"</span>,
    <span class="hljs-attr">component</span>: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">"@/pages/HomePage.vue"</span>)
  },
  {
    <span class="hljs-attr">path</span>: <span class="hljs-string">"/login"</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">"login"</span>,
    <span class="hljs-attr">component</span>: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">"@/pages/LoginPage.vue"</span>)
  }
]

<span class="hljs-keyword">const</span> router = createRouter({
  <span class="hljs-attr">history</span>: createWebHistory(),
  routes
})

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> router
</code></pre>
      <h3 id="t10315.3 HomePage.vue">15.3 HomePage.vue <a href="#t10315.3%20HomePage.vue"> # </a></h3>
      <p>src\pages\HomePage.vue</p>
      <pre><code class="lang-js">&lt;template&gt;
  &lt;h1&gt;Home&lt;/h1&gt;
&lt;/template&gt;
</code></pre>
      <h3 id="t10415.4 LoginPage.vue">15.4 LoginPage.vue <a href="#t10415.4%20LoginPage.vue"> # </a></h3>
      <p>src\pages\LoginPage.vue</p>
      <pre><code class="lang-js">&lt;template&gt;
  &lt;form&gt;
    用户名 &lt;input /&gt;
  &lt;/form&gt;
&lt;/template&gt;
</code></pre>
      <h3 id="t10515.5 src\main.ts">15.5 src\main.ts <a href="#t10515.5%20src\main.ts"> # </a></h3>
      <p>src\main.ts</p>
      <pre><code class="lang-js"><span class="hljs-keyword">import</span> { createApp } <span class="hljs-keyword">from</span> <span class="hljs-string">"vue"</span>
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">"./App.vue"</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">"./global.css"</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">"@/request"</span>
<span class="hljs-keyword">import</span> { createPinia } <span class="hljs-keyword">from</span> <span class="hljs-string">"pinia"</span>
+<span class="hljs-keyword">import</span> router <span class="hljs-keyword">from</span> <span class="hljs-string">"./router"</span>
<span class="hljs-keyword">const</span> app = createApp(App)
app.use(createPinia())
+app.use(router)
app.mount(<span class="hljs-string">"#app"</span>)

</code></pre>
      <h3 id="t10615.6 App.vue">15.6 App.vue <a href="#t10615.6%20App.vue"> # </a></h3>
      <p>src\App.vue</p>
      <pre><code class="lang-diff">&lt;script setup lang="ts"&gt;
import HelloWorld from "@/components/HelloWorld.vue"
import msg from "./msg"
&lt;/script&gt;

&lt;template&gt;
<span class="hljs-addition">+  &lt;router-view&gt;&lt;/router-view&gt;</span>
&lt;/template&gt;

&lt;style&gt;&lt;/style&gt;

</code></pre>
      <h2 id="t10716. UI 组件库">16. UI 组件库 <a href="#t10716.%20UI%20%E7%BB%84%E4%BB%B6%E5%BA%93"> #
        </a></h2>
      <ul>
        <li><a href="https://www.naiveui.com/zh-CN/os-theme">Naïve UI</a>是一个 Vue 3 组件库</li>
        <li><a href="https://v3.cn.vuejs.org/api/global-api.html#h">h</a>返回一个”虚拟节点“，通常缩写为 VNode,接收三个参数：type，props 和
          children</li>
        <li><a href="https://www.naiveui.com/zh-CN/os-theme/components/menu">menu</a></li>
      </ul>
      <h3 id="t10816.1 安装">16.1 安装 <a href="#t10816.1%20%E5%AE%89%E8%A3%85"> # </a></h3>
      <pre><code class="lang-js">pnpm install naive-ui vfonts @vicons/ionicons5
</code></pre>
      <h3 id="t10916.2 src\App.vue">16.2 src\App.vue <a href="#t10916.2%20src\App.vue"> # </a></h3>
      <ul>
        <li>Non-function value encountered for default slot. Prefer function slots for better performance.
          src\App.vue</li>
        <li><a href="https://v3.cn.vuejs.org/api/built-in-components.html#slot">slot</a>用于具名插槽</li>
      </ul>
      <pre><code class="lang-diff">&lt;script setup lang="ts"&gt;
import HelloWorld from "@/components/HelloWorld.vue"
import msg from "./msg"
<span class="hljs-addition">+import { h, Component } from "vue"</span>
<span class="hljs-addition">+import { NIcon, NMenu } from "naive-ui"</span>
<span class="hljs-addition">+import type { MenuOption } from "naive-ui"</span>
<span class="hljs-addition">+import { RouterLink } from "vue-router"</span>
<span class="hljs-addition">+import { HomeOutline, LogInOutline } from "@vicons/ionicons5"</span>
<span class="hljs-addition">+const menuOptions: MenuOption[] = [</span>
<span class="hljs-addition">+  {</span>
<span class="hljs-addition">+    label: () =&gt;</span>
<span class="hljs-addition">+      h(RouterLink, { to: { name: "home" } }, { default: () =&gt; "首页" }),</span>
<span class="hljs-addition">+    key: "home",</span>
<span class="hljs-addition">+    icon: () =&gt; h(NIcon, null, { default: () =&gt; h(HomeOutline) }) //带有插槽的对象</span>
<span class="hljs-addition">+  },</span>
<span class="hljs-addition">+  {</span>
<span class="hljs-addition">+    label: () =&gt;</span>
<span class="hljs-addition">+      h(RouterLink, { to: { name: "login" } }, { default: () =&gt; "登录" }),</span>
<span class="hljs-addition">+    key: "login",</span>
<span class="hljs-addition">+    icon: () =&gt; h(NIcon, null, { default: () =&gt; h(LogInOutline) })</span>
<span class="hljs-addition">+  }</span>
<span class="hljs-addition">+]</span>
&lt;/script&gt;

&lt;template&gt;
<span class="hljs-addition">+  &lt;n-menu :options="menuOptions" /&gt;</span>
  &lt;router-view&gt;&lt;/router-view&gt;
&lt;/template&gt;

&lt;style&gt;&lt;/style&gt;

</code></pre>
      <h2 id="t11017. 环境变量和模式">17. 环境变量和模式 <a
          href="#t11017.%20%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E5%92%8C%E6%A8%A1%E5%BC%8F">
          # </a></h2>
      <ul>
        <li>Vite 在一个特殊的 import.meta.env 对象上暴露<a href="https://vitejs.cn/guide/env-and-mode.html">环境变量</a>
          <ul>
            <li>import.meta.env.MODE: {string} 应用运行的模式</li>
            <li>import.meta.env.BASE_URL: {string} 部署应用时的基本 URL。他由 base 配置项决定</li>
            <li>import.meta.env.PROD: {boolean} 应用是否运行在生产环境</li>
            <li>import.meta.env.DEV: {boolean} 应用是否运行在开发环境 (永远与 import.meta.env.PROD 相反)</li>
          </ul>
        </li>
      </ul>
      <h3 id="t11117.1 .env.development">17.1 .env.development <a href="#t11117.1%20.env.development"> # </a></h3>
      <pre><code class="lang-js">VITE_APP_WEB_URL = <span class="hljs-string">"/dev"</span>
</code></pre>
      <h3 id="t11217.2 .env.production">17.2 .env.production <a href="#t11217.2%20.env.production"> # </a></h3>
      <pre><code class="lang-js">VITE_APP_WEB_URL = <span class="hljs-string">"/prod"</span>
</code></pre>
      <h3 id="t11317.3 src\main.ts">17.3 src\main.ts <a href="#t11317.3%20src\main.ts"> # </a></h3>
      <pre><code class="lang-diff"><span class="hljs-addition">+console.log(import.meta.env)</span>
</code></pre>
      <h3 id="t11417.4 package.json">17.4 package.json <a href="#t11417.4%20package.json"> # </a></h3>
      <p>package.json</p>
      <pre><code class="lang-diff">{
  "scripts": {
<span class="hljs-addition">+    "build:dev": "vue-tsc --noEmit &amp;&amp; vite build --mode development",</span>
<span class="hljs-addition">+    "build:prod": "vue-tsc --noEmit &amp;&amp; vite build --mode production",</span>
  },
}
</code></pre>

    </div>
  </div>

  <script src="./typescript6/jquerymin_1645176580555.js.下载"></script>
  <script src="./typescript6/bootstrapmin_1645176554753.js.下载"></script>

  <script>
    $('.warpper .page-toc ul ul li a').on('click', function () {
      $('.warpper .page-toc ul ul li a').removeClass('my-active')
      $(this).addClass('my-active')
    })
    $('.logo').on('mouseenter', function () {
      $('.nav').height('450px');
    })
    $('.nav').on('mouseleave', function () {
      $('.nav').height('80px');
    })
    $('.logo').on('click', function () {
      $('.nav').css('display', 'none');
      $('.warpper').css('padding', '0px');
    })
  </script>


</body>

</html>